Modern integrated circuits (ICs) are developed through the use of hardware description languages (HDLs). HDLs such as VERILOG, VHDL, and the like allow developers to create software-based representations of circuit designs. One advantage of using an HDL is the potential for code reuse from one design to another. This concept has been realized with the commercial availability of intellectual property (IP) cores.
In general, an IP core (hereafter “core”) refers to a software representation of a semiconductor component that provides a processing function. Different varieties of cores exist. For example, some cores can provide basic functions. These cores can be included in a circuit design or, alternatively, can be used as subcomponents within a larger, more complex core. When used within a larger core, the subcomponents are not directly accessible except by other subcomponent cores within the larger core. Another variety of core can function as a logic bridge to software-based bus objects such as Peripheral Component Interconnect (PCI) and/or Advanced Microcontroller Bus Architecture (AMBA) busses.
Two or more cores can be said to be related when the cores perform similar functions. A general example of related cores is the case where one core is configured to encode data and another core is configured to decode data. In high level terms, one core performs a function, and the other core performs the inverse of the function. Another example of related cores can be found within a Generic Framing Procedure (GFP) core, such as the GFP Core available from Xilinx, Inc. of San Jose, Calif.
The Xilinx GFP core implements the International Telecommunication Union's GFP recommendation (G.7041/Y.1303). Generally, this core includes a MAP core and an UNMAP core. The MAP core receives client network protocol data on the system interface, encapsulates this data, and transmits the resulting frames on the line interface. The UNMAP core performs a similar process in reverse. The UNMAP core receives encapsulated data on the line interface and de-maps the frames to extract client network protocol data. The network protocol data is, in turn, transmitted on the system interface.
While complementary cores are similar in terms of functionality, each can offer one or more functions which may not be included within the other core. As such, the functionality of one complementary core cannot be thought of strictly as the inverse of the other. In illustration, a MAP core can include user programmable channel configurations, while the UNMAP core may not include such functionality. Similarly, the UNMAP core can include synchronization logic to detect frame boundaries, which is not needed in the MAP core.
Before a core is released for commercial use, it must be thoroughly tested and verified. The core must be tested to ensure that it functions properly and as expected, particularly as defined in the design specification. Due to the complexity of modern cores, however, testing requires a significant amount of time. Frequently, core testing/verification requires as much time, if not more, than developing the core itself. This problem is exacerbated when more than one core is to be tested. Such is the case, for example, with related or complementary cores.
One way of testing complementary cores is to place the two cores in a loop-back configuration and design a testbench for this configuration. A loop-back configuration refers to placing the two cores in line, one after the other. Using GFP cores as an example, in a loop-back configuration, test data can be provided to the MAP core. The output of the MAP core can be fed to the input of the UNMAP core. If the cores function properly, the output of the UNMAP core should be identical to the data fed to the MAP core as input.
A testbench, also referred to as a verification environment, refers to HDL descriptions that specify and verify the behavior of a device under test, in this case one or more cores. Generating a testbench involves describing the connections, events, and test vectors for different combinations of transactions involving the core(s). A testbench also refers to the code used to create a pre-determined input sequence to the cores, as well as the code responsible for observing the response.
Typically, testbenches are manually coded by a developer. As such, testbench development tends to be a time consuming and error-prone process. By placing two complementary cores in a loop-back configuration, the number of testbenches can be reduced as inverse functions of the two cores can be tested using a single testbench.
The loop-back technique of testing complementary cores, however, does have limitations. With reference to GFP, for example, an UNMAP core should have the ability to process any type of management frame that is allowed by its specification. The MAP core may be more restricted in terms of frame generation. That is, the UNMAP core from a given provider may need to process more types of frames than the MAP core, from the same provider, is capable of generating. Such can be the case as MAP and UNMAP cores may be sold separately by the provider. Accordingly, is it important for the UNMAP core to be able to process a large variety of frame types, particularly in the event that it is paired with a MAP core from a different provider.
When conducting loop-back tests, the provider typically pairs its own complementary cores together. This can lead to a situation in which a MAP core is unable to generate all frame types that the complementary UNMAP core should be able to process. In illustration, if the MAP core cannot generate frames with payloads attached, but the UNMAP core is to have the ability to process such frames, loop-back type testing will not provide an adequate means for testing the UNMAP core's ability to process frames with payloads attached.
Another technique for testing complementary cores is to create one testbench for testing each function of the cores, thereby ensuring that any functions not shared among the complementary cores would be adequately tested. By testing each core independently, however, a significant number of tests are required for each core despite any overlap in functionality between the two cores. This additional overhead in terms of creating testbenches significantly increases the overall time needed to test and verify the cores. In some cases, this technique amounts to doubling the amount of time otherwise needed for testing and/or verification. As testing and verification can require as much or more time than designing a core, it can be seen that testing complementary cores in this manner requires an unacceptable amount of additional time and overhead.
It would be beneficial to provide a technique for testing cores in a manner that overcomes the limitations described above.